﻿using System;
using System.Linq;
using Csla;
using Csla.Data;
using Csla.Serialization;
using BizControl.DalLinq;
using BizControl.Library.BusinessObjects.People;
using BizControl.Library.BusinessObjects.Models;
using BizControl.Library.Criterias;
using BizControl.Library.Security;
using BizControl.Resources;
using System.Security;

namespace BizControl.Library.BusinessObjects.Categories
{
  [Serializable()]
  public class CategoryList : DynamicListBase<CategoryBO>
  {
    #region  Business Methods

    private ModelBO _model;

    public CategoryBO this[Guid? categoryId]
    {
      get
      {
        if (categoryId == null || categoryId == Guid.Empty)
          return CategoryBO.GetEmptyCategory();
        foreach (CategoryBO category in this)
        {
          if (category.CategoryId == categoryId)
            return category;
        }
        return CategoryBO.GetEmptyCategory();
      }
    }

    public CategoryBO AddCategory()
    {
      if (null != _model)
      {
        CategoryBO category = CategoryBO.NewCategory(_model);
        this.Add(category);
        return category;
      }
      else
      {
        throw new InvalidOperationException(ExceptionsMessages.ModelIsNotSetAddCategoryFail);
      }
    }

    public void Remove(Guid categoryId)
    {
      foreach (CategoryBO category in this)
      {
        if (category.CategoryId == categoryId)
        {
          Remove(category);
          break;
        }
      }
    }

    public bool Contains(Guid categoryId)
    {
      foreach (CategoryBO category in this)
        if (category.CategoryId == categoryId)
          return true;
      return false;
    }

    #endregion

    #region  Factory Methods

    public static CategoryList GetCategoryList(ModelBO model, bool includeEmptyCategory = false)
    {
      return DataPortal.Fetch<CategoryList>(new ModelAndBoolCriteria(model, includeEmptyCategory));
    }

    public static CategoryList GetCategoryList(bool includeEmptyCategory = false)
    {
      var model = SecurityChecks.GetCurrentModel();
      return DataPortal.Fetch<CategoryList>(new ModelAndBoolCriteria(model, includeEmptyCategory));
    }

    #endregion

    #region  Data Access

    private void DataPortal_Create(ModelBO model)
    {
      _model = model;
    }

    private void DataPortal_Fetch(ModelAndBoolCriteria criteria)
    {
      Fetch(criteria);
    }

    private void Fetch(ModelAndBoolCriteria criteria)
    {
      if (null == criteria.Model) throw new ArgumentNullException(ExceptionsMessages.ModelNullReference);
      _model = criteria.Model;
      RaiseListChangedEvents = false;
      using (var ctx = ContextManager<BusinessControl2DataContext>.GetManager(Database.BizControlDB))
      {
        var data = from c in ctx.DataContext.Categories
                   where !c.IsDeleted && c.Model == criteria.Model.ModelId
                   select CategoryBO.GetCategory(c.CategoryId);
        this.AddRange(data);
      }
      if (criteria.IncludeEmptyObject)
        this.Add(CategoryBO.GetEmptyCategory());
      RaiseListChangedEvents = true;
    }

    #endregion

  }
}